package server

import (
	"encoding/json"
	"log"

	"net/http"

	"github.com/corego/protoTrans/config"
	"github.com/labstack/echo"
	"github.com/sunface/talent"
	"github.com/valyala/fasthttp"
)

var client = &fasthttp.Client{}

func route(c echo.Context) error {
	defer func() {
		if err := recover(); err != nil {
			log.Println("[WARN] route error: ", err, c.QueryParams())
			talent.PrintStack(false)
		}
	}()

	buf := make([]byte, c.Request().ContentLength)
	_, err := c.Request().Body.Read(buf)
	if err != nil && !talent.IsEOF(err) {
		c.String(http.StatusOK, "decode http error: "+err.Error())
		log.Println("[WARN] decode error: ", err, buf)
		return nil
	}

	var d map[string]interface{}
	err = json.Unmarshal(buf, &d)
	if err != nil {
		c.String(http.StatusOK, "decode json error: "+err.Error())
		log.Println("[WARN] decode error: ", err, buf, string(buf))
		return nil
	}

	// log.Println("[WARN] aaaaaa http route decode suc", buf, string(buf))
	users, ok := d["msgto"]
	if !ok {
		c.String(http.StatusOK, "no users")
		log.Println("[WARN] cant find push users: ", err, d)
		return nil
	}

	var uList []string
	switch u := users.(type) {
	case string:
		uList = append(uList, u)
	case []interface{}:
		for _, v := range u {
			uList = append(uList, v.(string))
		}
	}

	route2mqtt(d, uList)

	return c.JSON(http.StatusOK, echo.Map{
		"code":   "200",
		"result": nil,
	})
}

func route2mqtt(d map[string]interface{}, users []string) {
	to := make(map[string]interface{})
	topic := d["resource"]
	if topic == nil {
		to["topic"] = "10001"
	}
	to["topic"] = "10001" + topic.(string)[3:]

	to["users"] = users

	msg := d["msgcontent"]
	to["message"] = msg

	iosMsg := d["iosMsg"]
	if iosMsg != nil {
		to["iosMsg"] = iosMsg
	}

	iosJSON := d["iosJSON"]
	if iosJSON != nil {
		to["iosJSON"] = iosJSON
	}

	msgType := d["msgType"]
	if msgType != nil {
		to["msgType"] = msgType
	}

	msgID := d["msgId"]
	if msgID != nil {
		to["msgID"] = msgID
	}

	expire := d["expire"]
	if expire != nil {
		to["expire"] = expire
	}

	toBuf, err := json.Marshal(to)
	if err != nil {
		log.Println("[WARN] encode to error: ", err, to)
		return
	}

	var arg fasthttp.Args
	arg.Parse(talent.Bytes2String(toBuf))
	code, body, err := client.Post(nil, config.Conf.Proto.MqttAddr, &arg)

	if code != 200 || err != nil {
		log.Println("[WARN] mqtt route error: ", msgID, code, err, talent.Bytes2String(body), ", msg: ", msg)
		return
	}

	log.Println("[INFO] mqtt route suc: ", msgID, code, talent.Bytes2String(body), err)
}
